
#include <BHBoxLayout>
#include <BTableItem>
#include <BListItem>
#include <BLineEdit>
#include <BClass>

#include "StringUtils.h"
#include "ScriptFormat.h"
#include "VariantBoard.h"

VariantBoard::VariantBoard(BWidget* parent) : BWidget(parent)
{
	_scrollToLastRow = false;

	_stackWidget = new BTableWidget();
	_stackWidget->setColumnCount(3);
	_stackWidget->setColumnLabel(0, "type");
	_stackWidget->setColumnLabel(1, "name");
	_stackWidget->setColumnLabel(2, "value");
	_stackWidget->setColumnWidth(0, 100);
	_stackWidget->setColumnWidth(1, 100);
	_stackWidget->setColumnWidth(2, 200);
	_stackWidget->setColumnPolicy(Policy_Preferred | Policy_Expanding);
	_stackWidget->setGridStyle(Grid_Crossing);
	BLayout* layout = new BLayout(this);
	layout->setWidget(_stackWidget);

	connect(_stackWidget, Signal_Fresh, &VariantBoard::slotStackFreshed);
}
VariantBoard::~VariantBoard()
{

}

void VariantBoard::setScript(BScript* script)
{
	_script = script;
}
BScript* VariantBoard::script() const
{
	return _script;
}

void VariantBoard::freshStack(const BVariantArray& stack)
{
	_stackWidget->clearItems();
	for (int i = 0; i < stack.size(); i++)
	{
		const BVariant& var = stack(i);
		int row = _stackWidget->addRows();
		_stackWidget->setRowLabel(row, row);
		if (BExp* exp = var.value())
		{
			switch (exp->syntax)
			{
			case Syntax_Begin:
				_stackWidget->setItem(row, 0, "begin");
				_stackWidget->setItem(row, 1, "----------------------");
				_stackWidget->setItem(row, 2, StringOfValue(exp->value));
				break;
			default:
				_stackWidget->setItem(row, 0, "exp:unknown");
				break;
			}
		}
		else
		{
			_stackWidget->setItem(row, 0, var.type());
			_stackWidget->setItem(row, 1, var.name());
			BString text;
			const BVariant* ptr = var.value();
			if (ptr)
			{
				text << "->" << ptr->name();
			}
			else
			{
				ptr = &var;
				if (BClass* cls = ptr->value())
					text << "ref_count : " << cls->ref_count();
				else
					text << StringOfValue(ptr->value());
			}
			_stackWidget->setItem(row, 2, text);
		}
		if (BTableItem* item = _stackWidget->item(row, 0))
		{
			ScriptFormat* format = new ScriptFormat();
			format->setScript(_script);
			format->update(item->text());
			item->setFormat(format);
		}
		if (BTableItem* item = _stackWidget->item(row, 2))
		{
			ScriptFormat* format = new ScriptFormat();
			format->setScript(_script);
			format->update(item->text());
			item->setFormat(format);
		}
	}
	_scrollToLastRow = true;
}

void VariantBoard::slotStackFreshed(BObject* object)
{
	if (_scrollToLastRow)
	{
		int lastRow = _stackWidget->rowCount() - 1;
		BTableItem* item = _stackWidget->item(lastRow, 0);
		_stackWidget->scrollToItem(item);
		_scrollToLastRow = false;
	}
}
